package Concurrency2.Chapter04_Visibility_Orderliness;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Instruction：Show Atomicity
 * Author：@author MaLi
 */
public class T01_Atomicity {
    private int sum = 0;
    private /*volatile*/ int result = 0;

    public static void main(String[] args) throws InterruptedException {
        //原子性问题现象1:
        //showProblem1();
        //原子性问题现象2:
        showProblem2();
    }

    /**
     * 原子性问题案例: 程序作为一个整体, 类似事务, 数据是一致的.
     */
    public void someMethod1() {
        try {
            System.out.println("someMethod1 start - sum: "+sum);
            sum = 100;
            System.out.println("线程1修改sum为: "+sum);
            TimeUnit.SECONDS.sleep(5);
            // 我们期望的值是100, 但实际输出值呢? 和上面sum=100的赋值产生的结果是一致的吗?
            System.out.println("someMethod1 end - sum: "+sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 原子性问题案例: 隐蔽的原子性问题
     */
    public void someMethod2() {
        for (int j = 0; j < 1000; j++) {
            result++;
        }
    }

    private static void showProblem2() throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(2);
        T01_Atomicity some = new T01_Atomicity();
        CountDownLatch latch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            service.submit(() -> {
                some.someMethod2();
                latch.countDown();
            });
        }
        latch.await();
        System.out.println("Result: "+some.result);
        service.shutdown();
    }

    private static void showProblem1() {
        ExecutorService service = Executors.newFixedThreadPool(2);
        T01_Atomicity some = new T01_Atomicity();
        service.submit(() -> {
            some.someMethod1();
        });
        service.submit(()->{
            some.sum=200;
            System.err.println("线程2修改sum为: "+some.sum);
        });
        service.shutdown();
    }
}
